<?php

/**
 *
 *
 * @author Rodrigo Rutkoski Rodrigues <rutkoski@gmail.com>
 * @package Simplify_Kernel_Core
 */
class Request
{

  const GET = 'GET';

  const POST = 'POST';

  protected $route;

  protected $extension;

  protected $pretty;

  protected $parsed = false;

  protected $post;

  protected $get;

  protected function parse()
  {
    if (! $this->parsed) {
      $this->parsed = true;

      $dirname = dirname($_SERVER['SCRIPT_NAME']);

      $regex = '#' . $dirname . '(?:(' . quotemeta($this->self()) . '))?(.*?)(?:\.([^\?]+))?(?:\?.*)?/*$#';

      if (! preg_match($regex, $this->uri(), $o)) {
        throw new Exception('Could not parse url');
      }

      $this->pretty = empty($o[1]);
      $this->route = $o[2];
      $this->extension = sy_get_param($o, 3);
    }

    return $this;
  }

  /**
   *
   * @return string
   */
  public function pretty()
  {
    return $this->parse()->pretty;
  }

  /**
   *
   * @return string
   */
  public function method($method = null)
  {
    if (! is_null($method)) {
      return $_SERVER['REQUEST_METHOD'] == strtoupper($method);
    }

    return $_SERVER['REQUEST_METHOD'];
  }

  /**
   *
   * @return boolean
   */
  public function ajax()
  {
    return getenv('HTTP_X_REQUESTED_WITH') === "XMLHttpRequest";
  }

  /**
   *
   * @return boolean
   */
  public function json()
  {
    return $this->parse()->extension == 'json';
  }

  /**
   *
   * @return boolean
   */
  public function xml()
  {
    return $this->parse()->extension == 'xml';
  }

  /**
   *
   */
  public function post($name = null, $default = null)
  {
    if (! $this->post) {
      $this->post = sy_strip_slashes_deep($_POST);
    }

    if (! is_null($name)) {
      return sy_get_param($this->post, $name, $default);
    }

    return new DataView($this->post);
  }

  /**
   *
   */
  public function get($name = null, $default = null)
  {
    if (! $this->get) {
      $this->get = sy_strip_slashes_deep($_GET);
    }

    if (! is_null($name)) {
      return sy_get_param($this->get, $name, $default);
    }

    return new DataView($this->get);
  }

  /**
   *
   */
  public function set($name, $value = null)
  {
    $this->get();
    $this->get[$name] = $value;
  }

  /**
   *
   * @return string
   */
  public function route()
  {
    return $this->parse()->route;
  }

  /**
   *
   * @return string
   */
  public function extension()
  {
    return $this->parse()->extension;
  }

  /**
   *
   * @return string
   */
  public function uri()
  {
    if (! isset($_SERVER['REQUEST_URI'])) {
      if (isset($_SERVER['REQUEST_URI'])) {
        $_SERVER['REQUEST_URI'] = $_SERVER['REQUEST_URI'];
      }
      elseif (isset($_SERVER['QUERY_STRING'])) {
        $_SERVER['REQUEST_URI'] = $_SERVER['SCRIPT_NAME'] . '?' . $_SERVER['QUERY_STRING'];
      }
      else {
        $_SERVER['REQUEST_URI'] = $_SERVER['SCRIPT_NAME'];
      }
    }

    if (isset($_SERVER['REQUEST_URI'])) {
      $uri = $_SERVER['REQUEST_URI'];
    }
    else {
      $uri = $_SERVER['ORIG_PATH_INFO'];
    }

    return $uri;
  }

  /**
   *
   * @return string
   */
  public function base()
  {
    return ($this->secure() ? 'https' : 'http') . '://' . $_SERVER['HTTP_HOST'];
  }

  /**
   *
   * @return string
   */
  public function url()
  {
    $dir = dirname($_SERVER['SCRIPT_NAME']);
    if ($dir == '/') $dir = '';
    return $this->base() . $dir;
  }

  /**
   *
   * @return boolean
   */
  public function secure()
  {
    return empty($_SERVER["HTTPS"]) ? '' : ($_SERVER["HTTPS"] == "on") ? "s" : "";
  }

  /**
   *
   * @return string
   */
  public function self()
  {
    return basename($_SERVER['SCRIPT_NAME']);
  }

  /**
   *
   * @return string
   */
  public function ip()
  {
    if (! empty($_SERVER['HTTP_CLIENT_IP'])) {
      $ip = $_SERVER['HTTP_CLIENT_IP'];
    }
    elseif (! empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
      $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
    }
    else {
      $ip = $_SERVER['REMOTE_ADDR'];
    }

    return $ip;
  }

  /**
   * Test if $route matches current requested route.
   *
   * @param string $regex
   * @param mixed $true
   * @param mixed $false
   * @return $true if $regex matches current route, $false otherwise
   */
  public function match($regex, $true, $false = '')
  {
    $regex = '|^' . $regex . '$|i';
    $match = preg_match($regex, $this->route()) ? $true : $false;
    return $match;
  }

}
